package com.yanqu.road.logic.cross;

import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.entity.enums.eBigRankType;
import com.yanqu.road.entity.rank.cross.CrossUserRank;
import com.yanqu.road.logic.bussiness.rank.RankBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.helper.RankListHelper;
import com.yanqu.road.logic.pb.CrossRankPb;
import com.yanqu.road.logic.sort.CrossRankSort;
import com.yanqu.road.pb.rank.RankProto;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.OptionalInt;
import java.util.Set;
import java.util.stream.IntStream;

public class CrossGroupWeekRankListModel {

    private int bigRankType;

    private int rankNum = GameConfig.RANK_DEFAULT_MAX_COUNT;

    private CrossRankSort crossRankSort;

    private boolean isUpdate = false;

    private boolean isNeedSync = false;

    private LinkedList<CrossUserRank> rankList;

    private int rankType;

    private int groupId;

    private int weekId;

    private RankProto.RankListMsg.Builder rankListMsg;

    public CrossGroupWeekRankListModel(int groupId, int weekId, int bigRankType, int rankType) {
        crossRankSort = new CrossRankSort();
        rankList = new LinkedList<>();
        rankListMsg = RankProto.RankListMsg.newBuilder();
        this.groupId = groupId;
        this.weekId = weekId;
        this.bigRankType = bigRankType;
        this.rankType = rankType;
    }

    public int getBigRankType() {
        return bigRankType;
    }

    public int getGroupId() {
        return groupId;
    }

    public int getWeekId() {
        return weekId;
    }

    public int getRankType() {
        return rankType;
    }

    public boolean isNeedSync() {
        return isNeedSync;
    }

    public void setNeedSync(boolean needSync) {
        isNeedSync = needSync;
    }

    public boolean isUpdate() {
        return isUpdate;
    }

    public void setUpdate(boolean update) {
        isUpdate = update;
    }

    public RankProto.RankListMsg.Builder getRankListMsg() {
        return rankListMsg;
    }

    public LinkedList<CrossUserRank> getRankList() {
        synchronized (this) {
            return new LinkedList<>(rankList);
        }
    }

    public void setRankList(LinkedList<CrossUserRank> userRankList) {
        synchronized (this) {
            rankList = new LinkedList<>(userRankList);
            RankListHelper.checkUserRankListValid(rankList);       //校验一下数组
            rankList.sort(crossRankSort);
            while (rankList.size() > rankNum){
                rankList.removeLast();
            }
            initRankMsg();
        }
    }

    private void initRankMsg() {
        rankListMsg = CrossRankPb.parseRankListMsg(rankList);
    }

    public int getMyRank(long userId, long serverId) {
        synchronized (this) {
            OptionalInt result = IntStream.range(0, rankList.size()).filter(i -> rankList.get(i).getUserId() == userId &&
                    rankList.get(i).getUserBaseInfo().getServerId() == serverId).findFirst();
            if (result.isPresent()) {
                return result.getAsInt() + 1;
            }
            return -1;
        }
    }

    public LinkedList<CrossUserRank> removeRank(Set<Long> serverIdSet) {
        LinkedList<CrossUserRank> result = new LinkedList<>();
        synchronized (this) {
            Iterator<CrossUserRank> iterator = rankList.iterator();
            while(iterator.hasNext()){
                CrossUserRank rank = iterator.next();
                if(!serverIdSet.contains(rank.getUserBaseInfo().getServerId())){
                    if(rank.getValue().compareTo(BigInteger.ZERO) > 0) {
                        result.add(rank.clone());
                        rank.setValue(BigInteger.ZERO);
                        iterator.remove();    //策划需求要优化
                    }
                }
            }
            if(result.size() > 0) {
                rankList.sort(crossRankSort);
                initRankMsg();
                isUpdate = true;
                isNeedSync = true;
            }
        }
        return result;
    }

    /**
     * 添加到排行
     */
    public void rankChange(CrossUserRank crossUserRank) {
        boolean isChange = false;
        synchronized (this) {
            int size = rankList.size();
            if (!rankList.stream().anyMatch(predicate -> predicate.getUserId() == crossUserRank.getUserId() &&
                    predicate.getUserBaseInfo().getServerId() == crossUserRank.getUserBaseInfo().getServerId())) {
                if (size < rankNum) {
                    CrossUserRank rank = crossUserRank.clone();
                    rank.setLastUpdateTime(System.currentTimeMillis() / 1000);
                    rankList.add(rank);
                    isChange = true;
                } else if (rankList.getLast().getValue().compareTo(crossUserRank.getValue()) < 0) {
                    replaceLastRank(crossUserRank);
                    isChange = true;
                } else if ((bigRankType == eBigRankType.Skin.getValue() || bigRankType == eBigRankType.Patrons.getValue() || bigRankType == eBigRankType.Beauty.getValue()) &&
                        rankList.getLast().getValue().compareTo(crossUserRank.getValue()) == 0) {
                    JSONObject lastObject = JSONObject.parseObject(rankList.getLast().getParam());
                    JSONObject curObject = JSONObject.parseObject(crossUserRank.getParam());
                    BigInteger vLast = StringUtils.isNullOrEmpty(lastObject.getString("value")) ? BigInteger.ZERO : lastObject.getBigInteger("value");
                    BigInteger vCur = StringUtils.isNullOrEmpty(curObject.getString("value")) ? BigInteger.ZERO : curObject.getBigInteger("value");
                    if (vLast.compareTo(vCur) < 0) {
                        replaceLastRank(crossUserRank);
                        isChange = true;
                    }
                } else if (bigRankType == eBigRankType.Vehicle.getValue() && rankList.getLast().getValue().compareTo(crossUserRank.getValue()) == 0) {
                    JSONObject lastObject = JSONObject.parseObject(rankList.getLast().getParam());
                    JSONObject curObject = JSONObject.parseObject(crossUserRank.getParam());
                    // 赚钱比较
                    int lastAddi = StringUtils.isNullOrEmpty(lastObject.getString("addition")) ? 0 : lastObject.getInteger("addition");
                    int curAddi = StringUtils.isNullOrEmpty(curObject.getString("addition")) ? 0 : curObject.getInteger("addition");
                    if (curAddi > lastAddi) {
                        replaceLastRank(crossUserRank);
                        isChange = true;
                    }
                }
            } else {
                rankList.forEach(action -> {
                    if (action.getUserId() == crossUserRank.getUserId() && action.getUserBaseInfo().getServerId() == crossUserRank.getUserBaseInfo().getServerId()) {
                        action.setUserBaseInfo(crossUserRank.getUserBaseInfo());
                        action.setValue(crossUserRank.getValue());
                        action.setLastUpdateTime(System.currentTimeMillis() / 1000);
                        action.setParam(crossUserRank.getParam());
                    }
                });
                isChange = true;
            }
            if(isChange) {
                rankList.sort(crossRankSort);
                initRankMsg();
                isUpdate = true;
                isNeedSync = true;
            }
        }
    }

    public BigInteger getMinRankScore() {
        synchronized (this) {
            if (rankList.size() > 0 && rankList.size() >= rankNum) {
                return rankList.getLast().getValue();
            }
            return BigInteger.ZERO;
        }
    }

    public void setRankNum(int rankNum) {
        this.rankNum = rankNum;
    }

    public void saveRankList() {
        LinkedList<CrossUserRank> newRankList;
        synchronized (this) {
            if (!isUpdate) {
                return;
            }
            newRankList = new LinkedList<>(rankList);
            isUpdate = false;
        }
        RankBussiness.updateCrossGroupWeekRankList(newRankList, groupId, weekId);
    }

    /**
     * 替换榜单最后一名
     */
    private CrossUserRank replaceLastRank(CrossUserRank crossUserRank) {
        CrossUserRank rank = rankList.getLast();
        rank.setUserId(crossUserRank.getUserId());
        rank.setUserBaseInfo(crossUserRank.getUserBaseInfo());
        rank.setValue(crossUserRank.getValue());
        rank.setLastUpdateTime(System.currentTimeMillis() / 1000);
        rank.setParam(crossUserRank.getParam());
        return rank;
    }
}
